package com.data.mall.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

public class ExecutorManager {

    private static final Logger LOGGER = LoggerFactory.getLogger(ExecutorManager.class);
    /**
     * 线程池
     */
    private static ThreadPoolExecutor pool;

    private final static int DEFAULT_THREAD_NUM = Runtime.getRuntime().availableProcessors();
    private static ReentrantLock lock = new ReentrantLock();
    private static int THREAD_NUM = DEFAULT_THREAD_NUM;
    private static int BLOCK_QUEUE_SIZE = 30000;
    private static final int KEEP_ALIVE_TIME = 60;
    private static volatile ExecutorManager instance;

    private ExecutorManager() {
        pool = new ThreadPoolExecutor(THREAD_NUM, THREAD_NUM, KEEP_ALIVE_TIME, TimeUnit.SECONDS, new LinkedBlockingQueue<>(BLOCK_QUEUE_SIZE), new NameThreadFactory("DelayQueue"));
        pool.allowCoreThreadTimeOut(true);
        Runtime.getRuntime().addShutdownHook(new Thread(this::shutDown));
    }


    public static ExecutorManager getInstance() {
        if (null == instance) {
            lock.lock();
            try {
                if (null == instance) {
                    instance = new ExecutorManager();
                }
            } finally {
                lock.unlock();
            }
        }
        return instance;
    }

    public void execute(Runnable worker) {
        pool.execute(worker);
    }

    public void shutDown() {
        LOGGER.info("关闭延时队列管理线程池...");
        if (pool != null) {
            pool.shutdown();
            pool = null;
        }
    }
}
